﻿using System;
using System.Collections.Generic;
using Snake.Logger;

namespace Snake.Gameplay
{
    internal class GameplayTagContainerNode
    {
        private string _key;
        private GameplayTagContainerNode _parent;

        private int _count;
        private int _childCountSum;

        private readonly Dictionary<string, GameplayTagContainerNode> _nodes =
            new Dictionary<string, GameplayTagContainerNode>();

        public event Action OnValueChanged;

        public int Count => _count + _childCountSum;

        public GameplayTagContainerNode(string key = "root")
        {
            _key = key;
        }

        private GameplayTagContainerNode(GameplayTagContainerNode parent, string key)
        {
            _parent = parent;
            _key = key;
        }

        public GameplayTagContainerNode FindNode(string key)
        {
            if (_nodes.TryGetValue(key, out var node))
            {
                return node;
            }

            node = new GameplayTagContainerNode(this, key);
            node.OnValueChanged += Calculate;
            _nodes.Add(key, node);
            return node;
        }

        public void SetTag(int val)
        {
            _count = val;
            OnValueChanged?.Invoke();
        }

        public void Add(int val = 1)
        {
            _count += val;
            OnValueChanged?.Invoke();
        }

        public void Remove(int val = 1)
        {
            if (_count == 0)
            {
                Log.Warn("当前节点数量为0，不能再减少了");
                return;
            }

            _count -= val;
            OnValueChanged?.Invoke();
        }

        public void RemoveAll()
        {
            _count = 0;
            _childCountSum = 0;
            _nodes.Clear();
            OnValueChanged?.Invoke();
        }

        private void Calculate()
        {
            _childCountSum = 0;
            foreach (var node in _nodes.Values)
            {
                _childCountSum += node.Count;
            }
        }
    }
}